// 导航守卫  页面访问权限
// 需求：只有登录后才能访问系统中页面（除了登录和404页面之外）
// 我们只需要判断token是否存在即可，当token存在说已登录 否则未登录
import router from './router'
import store from './store'

// 全局前置导航守卫：本质上就是在路由页面跳转之前会触发的一个函数
router.beforeEach(async(to, from, next) => {
  if (store.state.user.token) {
    // 已登录
    // 需求：当系统已经是登录状态了，那么不需要跳转到登录，如果访问的是登录页面重新跳转到首页即可
    if (to.path === '/login') {
      next('/')
    } else {
      // 获取用户信息
      // 页面跳转也会触发这里，但是只是页面跳转vuex数据是不会丢失的，因此没有必须再调用接口获取数据，
      // 只有刷新浏览器的时候会清空vuex数据，此刻才需要调用接口重新获取数据，那如何判断呢？
      // 答：我们只需判断userInfo对象是有数据即可
      if (!store.state.user.userInfo.userId) {
        // 注意：我们这里不能直接拿userInfo来判断，因为userInfo初始值是一个空对象
        // 而一个对象，无论是否存在属性都是true，因此不能直接拿它来判断
        // 因此我们可以拿对象里面的属性进行判断即可，我们这里拿userId来判断
        // 因此userId只要用户的登录并且获取到了用户信息，它的值就一定是存在的
        await store.dispatch('user/getUserInfo')
        // 调用筛选动态路由的函数，在这里获取动态路由的信息目的之一，
        // 就是为了保存能够获取到menus数组
        const res = await store.dispatch('permission/filterRoutes', store.state.user.userInfo.menus)
        // 加到路由规则里
        router.addRoutes([...res, { path: '*', redirect: '/404', hidden: true }])
      }
      next() // 放行函数
    }
  } else {
    // 未登录  跳转到登录页面4
    // 当访问的页面本来就是登录页面或者404页面的时候需要直接放行
    const writeArr = ['/login', '/404'] // 白名单，所有在白名单内的页面都可以直接访问
    // if (to.path === '/login' || to.path === '/404') { // 这种方式做判断，不利用扩展
    // 只需要判断到我们访问的目标路由路径 存在在白名单数组中即可说明该页面是可以直接访问的
    // includes方法 查找数组中是否存在某个元素，存在则返回true否则返回false
    if (writeArr.includes(to.path)) {
      next()
    } else {
      // 执行这行代码的时候会不会重新触发导航守卫 ？
      //  答：会，因为next方法传入路径是跳转，不是放行。
      next('/login')
    }
  }
})

